/**
 * 用户认证状态管理模块
 * 负责用户登录状态、令牌管理和持久化存储
 */

import { ref, reactive } from 'vue'
import { apiClient, initializeApi, type User, type LoginResponse } from './api'

// 用户状态接口
export interface AuthState {
  isLoggedIn: boolean
  user: User | null
  accessToken: string
  refreshToken: string
  serverUrl: string
}

// 本地存储键名
const STORAGE_KEYS = {
  ACCESS_TOKEN: 'linkbook-access-token',
  REFRESH_TOKEN: 'linkbook-refresh-token',
  USER_INFO: 'linkbook-user-info',
  SERVER_URL: 'linkbook-server-url',
  IS_LOGGED_IN: 'linkbook-is-logged-in'
}

// 全局认证状态
export const authState = reactive<AuthState>({
  isLoggedIn: false,
  user: null,
  accessToken: '',
  refreshToken: '',
  serverUrl: 'http://localhost:8000'
})

// 响应式登录状态
export const isLoggedIn = ref(false)

/**
 * 从本地存储加载认证状态
 */
export function loadAuthState(): void {
  try {
    const savedAccessToken = localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN)
    const savedRefreshToken = localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN)
    const savedUserInfo = localStorage.getItem(STORAGE_KEYS.USER_INFO)
    const savedServerUrl = localStorage.getItem(STORAGE_KEYS.SERVER_URL)
    const savedIsLoggedIn = localStorage.getItem(STORAGE_KEYS.IS_LOGGED_IN)

    console.log('加载认证状态:', {
      hasAccessToken: !!savedAccessToken,
      hasRefreshToken: !!savedRefreshToken,
      hasUserInfo: !!savedUserInfo,
      serverUrl: savedServerUrl,
      isLoggedIn: savedIsLoggedIn
    })

    if (savedServerUrl) {
      authState.serverUrl = savedServerUrl
      initializeApi(savedServerUrl)
    }

    if (savedAccessToken && savedRefreshToken && savedUserInfo && savedIsLoggedIn === 'true') {
      authState.accessToken = savedAccessToken
      authState.refreshToken = savedRefreshToken
      authState.user = JSON.parse(savedUserInfo)
      authState.isLoggedIn = true
      isLoggedIn.value = true

      // 设置API客户端的访问令牌
      apiClient.setAccessToken(savedAccessToken)

      console.log('已从本地存储恢复登录状态，token前缀:', savedAccessToken.substring(0, 20))
    } else {
      console.log('本地存储中没有有效的登录状态')
    }
  } catch (error) {
    console.error('加载认证状态失败:', error)
    clearAuthState()
  }
}

/**
 * 保存认证状态到本地存储
 */
export function saveAuthState(): void {
  try {
    console.log('准备保存认证状态:', {
      isLoggedIn: authState.isLoggedIn,
      hasUser: !!authState.user,
      hasAccessToken: !!authState.accessToken,
      hasRefreshToken: !!authState.refreshToken,
      accessTokenPrefix: authState.accessToken ? authState.accessToken.substring(0, 20) : 'none'
    })

    if (authState.isLoggedIn && authState.user) {
      localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, authState.accessToken)
      localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, authState.refreshToken)
      localStorage.setItem(STORAGE_KEYS.USER_INFO, JSON.stringify(authState.user))
      localStorage.setItem(STORAGE_KEYS.SERVER_URL, authState.serverUrl)
      localStorage.setItem(STORAGE_KEYS.IS_LOGGED_IN, 'true')
      
      console.log('认证状态已保存到localStorage，token前缀:', authState.accessToken.substring(0, 20))
      
      // 验证保存是否成功
      const savedToken = localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN)
      console.log('验证保存结果，从localStorage读取的token前缀:', savedToken ? savedToken.substring(0, 20) : 'null')
    } else {
      console.log('认证状态不完整，清除localStorage')
      clearStoredAuthState()
    }
  } catch (error) {
    console.error('保存认证状态失败:', error)
  }
}

/**
 * 清除本地存储的认证状态
 */
function clearStoredAuthState(): void {
  localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN)
  localStorage.removeItem(STORAGE_KEYS.REFRESH_TOKEN)
  localStorage.removeItem(STORAGE_KEYS.USER_INFO)
  localStorage.removeItem(STORAGE_KEYS.IS_LOGGED_IN)
}

/**
 * 清除认证状态
 */
export function clearAuthState(): void {
  authState.isLoggedIn = false
  authState.user = null
  authState.accessToken = ''
  authState.refreshToken = ''
  isLoggedIn.value = false

  // 清除API客户端的访问令牌
  apiClient.setAccessToken('')

  // 清除本地存储
  clearStoredAuthState()

  console.log('已清除认证状态')
}

/**
 * 用户登录
 * @param email 邮箱
 * @param password 密码
 * @param serverUrl 服务器地址
 * @returns Promise<{success: boolean, message?: string}>
 */
export async function login(
  email: string,
  password: string,
  serverUrl: string
): Promise<{success: boolean, message?: string}> {
  try {
    // 设置服务器地址
    authState.serverUrl = serverUrl
    initializeApi(serverUrl)

    // 发送登录请求
    const response = await apiClient.login({ email, password })

    if (response.success && response.data) {
      const loginData = response.data as LoginResponse
      
      console.log('登录响应数据:', {
        hasUser: !!loginData.user,
        hasAccessToken: !!loginData.access,
        hasRefreshToken: !!loginData.refresh,
        accessTokenPrefix: loginData.access ? loginData.access.substring(0, 20) : 'none',
        userEmail: loginData.user?.email
      })

      // 更新认证状态
      authState.isLoggedIn = true
      authState.user = loginData.user
      authState.accessToken = loginData.access
      authState.refreshToken = loginData.refresh
      isLoggedIn.value = true

      console.log('authState更新后:', {
        isLoggedIn: authState.isLoggedIn,
        hasUser: !!authState.user,
        accessTokenPrefix: authState.accessToken ? authState.accessToken.substring(0, 20) : 'none'
      })

      // 设置API客户端的访问令牌
      apiClient.setAccessToken(loginData.access)

      // 保存到本地存储
      saveAuthState()

      console.log('登录成功:', loginData.user.email)
      return { success: true }
    } else {
      return {
        success: false,
        message: response.error || '登录失败'
      }
    }
  } catch (error) {
    console.error('登录过程中发生错误:', error)
    return {
      success: false,
      message: error instanceof Error ? error.message : '登录失败'
    }
  }
}

/**
 * 用户注册
 * @param email 邮箱
 * @param password 密码
 * @param serverUrl 服务器地址
 * @param username 用户名（可选）
 * @returns Promise<{success: boolean, message?: string}>
 */
export async function register(
  email: string,
  password: string,
  serverUrl: string,
  username?: string
): Promise<{success: boolean, message?: string}> {
  try {
    // 设置服务器地址
    authState.serverUrl = serverUrl
    initializeApi(serverUrl)

    // 发送注册请求
    const response = await apiClient.register({ username: username || email.split('@')[0], password, email })

    if (response.success) {
      console.log('注册成功:', email)
      return { success: true, message: '注册成功，请登录' }
    } else {
      return {
        success: false,
        message: response.error || '注册失败'
      }
    }
  } catch (error) {
    console.error('注册过程中发生错误:', error)
    return {
      success: false,
      message: error instanceof Error ? error.message : '注册失败'
    }
  }
}

/**
 * 用户登出
 * @returns Promise<void>
 */
export async function logout(): Promise<void> {
  try {
    // 发送登出请求（可选，即使失败也要清除本地状态）
    if (authState.isLoggedIn) {
      await apiClient.logout()
    }
  } catch (error) {
    console.error('登出请求失败:', error)
  } finally {
    // 清除认证状态
    clearAuthState()
    console.log('已登出')
  }
}

/**
 * 刷新访问令牌
 * @returns Promise<boolean>
 */
export async function refreshAccessToken(): Promise<boolean> {
  try {
    if (!authState.refreshToken) {
      console.warn('没有刷新令牌，无法刷新访问令牌')
      return false
    }

    const response = await apiClient.refreshToken(authState.refreshToken)

    if (response.success && response.data) {
      // 处理新的返回格式：{access, refresh}
      if (response.data.access && response.data.refresh) {
        authState.accessToken = response.data.access
        authState.refreshToken = response.data.refresh
        apiClient.setAccessToken(response.data.access)
        saveAuthState()
        console.log('访问令牌和刷新令牌已更新')
        return true
      }
      // 兼容旧格式：{access_token}
      else if (response.data.access_token) {
        authState.accessToken = response.data.access_token
        apiClient.setAccessToken(response.data.access_token)
        saveAuthState()
        console.log('访问令牌已刷新')
        return true
      }
      else {
        console.error('刷新令牌响应格式不正确:', response.data)
        clearAuthState()
        return false
      }
    } else {
      console.error('刷新访问令牌失败:', response.error)
      // 刷新失败，清除认证状态并显示登录提示
      await handleTokenRefreshFailure()
      return false
    }
  } catch (error) {
    console.error('刷新访问令牌过程中发生错误:', error)
    // 刷新失败，清除认证状态并显示登录提示
    await handleTokenRefreshFailure()
    return false
  }
}

/**
 * 处理Token刷新失败的情况
 * 清除认证状态并显示登录提示
 */
async function handleTokenRefreshFailure(): Promise<void> {
  try {
    // 清除认证状态
    clearAuthState()
    
    // 显示登录过期通知
    showTokenExpiredNotification()
    
    // 触发全局事件，通知UI显示登录框
    window.dispatchEvent(new CustomEvent('auth:expired', {
      detail: { message: '登录已过期，请重新登录' }
    }))
    
    console.log('Token刷新失败，用户需要重新登录')
  } catch (error) {
    console.error('处理Token刷新失败时出错:', error)
  }
}

/**
 * 获取当前用户信息
 * @returns Promise<User | null>
 */
export async function getCurrentUser(): Promise<User | null> {
  try {
    if (!authState.isLoggedIn) {
      return null
    }

    const response = await apiClient.getCurrentUser()

    if (response.success && response.data) {
      authState.user = response.data
      saveAuthState()
      return response.data
    } else {
      console.error('获取用户信息失败:', response.error)
      return null
    }
  } catch (error) {
    console.error('获取用户信息过程中发生错误:', error)
    return null
  }
}

/**
 * 修改密码
 * @param oldPassword 旧密码
 * @param newPassword 新密码
 * @returns Promise<{success: boolean, message?: string}>
 */
export async function changePassword(
  oldPassword: string,
  newPassword: string
): Promise<{success: boolean, message?: string}> {
  try {
    if (!authState.isLoggedIn) {
      return { success: false, message: '请先登录' }
    }

    const response = await apiClient.changePassword({
      old_password: oldPassword,
      new_password: newPassword
    })

    if (response.success) {
      return { success: true, message: '密码修改成功' }
    } else {
      return {
        success: false,
        message: response.error || '密码修改失败'
      }
    }
  } catch (error) {
    console.error('修改密码过程中发生错误:', error)
    return {
      success: false,
      message: error instanceof Error ? error.message : '密码修改失败'
    }
  }
}

/**
 * 检查令牌是否即将过期并自动刷新
 * @returns Promise<void>
 */
export async function checkAndRefreshToken(): Promise<void> {
  if (!authState.isLoggedIn || !authState.accessToken) {
    return
  }

  try {
    // 尝试获取用户信息来检查令牌是否有效
    const response = await apiClient.getCurrentUser()
    
    if (!response.success) {
      // 如果获取用户信息失败，尝试刷新令牌
      console.log('访问令牌可能已过期，尝试刷新...')
      const refreshed = await refreshAccessToken()
      if (!refreshed) {
        console.log('令牌刷新失败，需要重新登录')
        // 显示提醒并清除认证状态
        showTokenExpiredNotification()
      } else {
        console.log('令牌刷新成功')
      }
    }
  } catch (error) {
    console.error('检查令牌状态失败:', error)
    // 网络错误或其他异常，尝试刷新令牌
    const refreshed = await refreshAccessToken()
    if (!refreshed) {
      showTokenExpiredNotification()
    }
  }
}

/**
 * 显示令牌过期提醒
 */
function showTokenExpiredNotification(): void {
  // 使用原生通知或者简单的alert
  if ('Notification' in window && Notification.permission === 'granted') {
    new Notification('LinkBook', {
      body: '登录已过期，请重新登录',
      icon: '/icon.png'
    })
  } else {
    alert('登录已过期，请重新登录')
  }
  
  // 延迟一下再清除状态，让用户看到提醒
  setTimeout(() => {
    clearAuthState()
    // 可以在这里触发显示登录界面的事件
    window.dispatchEvent(new CustomEvent('auth:expired'))
  }, 1000)
}

// 初始化时加载认证状态
loadAuthState()

// 定期检查令牌状态（每30分钟）
setInterval(checkAndRefreshToken, 30 * 60 * 1000)